import { ITask } from "@/Controller/State/task";
import QueueAnim from "rc-queue-anim";
import React from "react";
import styles from './index.module.less';
import Controller from "@/Controller";
import Icon from '@ant-design/icons';
import I001Svg from './svgs/I001.svg?react';
import I002Svg from './svgs/I002.svg?react';
import I003Svg from './svgs/I003.svg?react';
import { suspend } from "@/utils";
import classnames from 'classnames'
import { Button } from "antd";
import { TaskContext, useTask } from "@/hooks/useTask";

export interface IWindowItemProps {
    task: ITask;
}

export function WindowItem(props: IWindowItemProps) {

    const [show, setShow] = React.useState(true);
    const { task } = props;
    const self = React.useRef<HTMLDivElement>(null);

    const taskInfoList = Controller.instance.useMemo(s => s.taskInfo.list, [])

    /** 默认状态 */
    const defaultStyle: React.CSSProperties = {
        top: task.y,
        left: task.x,
        width: task.width,
        height: task.height,
        zIndex: task.zIndex,
    }

    /** 最小化 */
    const minimizeStyle: React.CSSProperties = {
        ...defaultStyle,
        opacity: 0,
        pointerEvents: 'none',
    }

    return (
        <TaskContext.Provider value={task}>
            <QueueAnim
                animConfig={[
                    { opacity: [1, 0], scaleX: [1, 1], scaleY: [1, 0] },
                ]}
            >
                {
                    show
                        ? <div
                            key="a"
                            ref={self}
                            className={classnames(styles.windowItem, { [styles.focus]: task.zIndex === taskInfoList.length - 1 })}
                            onMouseDown={() => { Controller.instance.askToTop({ id: task.id }) }}
                            style={(task.isMinimize && task.minimize) ? minimizeStyle : defaultStyle}
                        >
                            <Head {...props} setShow={setShow} />
                            <div className={styles.body} >
                                <input type="text" />
                                <Button>12</Button>
                            </div>
                            <Zoom />
                        </div>
                        : null
                }
            </QueueAnim>
        </TaskContext.Provider>
    )
}

/** 头部 */
function Head(props: { setShow: React.Dispatch<React.SetStateAction<boolean>> }) {

    const { task } = useTask();

    const { onMouseDown } = useDrag();

    return (
        <div
            className={classnames(styles.head)}
            onMouseDown={onMouseDown}
        >
            <Icon component={task.icon} style={{ fontSize: 16 }} />
            <span>{task.name}</span>
            <div style={{ flex: 1 }} ></div>
            <Minimize />
            <Close {...props} />
        </div>
    )
}

/** 最小化 */
function Minimize() {

    const { task, hideTask } = useTask();

    if (task.isMinimize) {
        return (
            <Icon
                onClick={hideTask}
                className={styles.close}
                component={I003Svg}
            />
        )
    } else {
        <></>
    }
}

/** 缩放按钮 */
function Zoom() {
    const { task } = useTask();

    /** 鼠标启示位置 */
    const startingPoint = React.useRef({ x: 0, y: 0 })

    /** 窗口原始位置 */
    const originalPoint = React.useRef({ x: 0, y: 0 })

    /** 鼠标按下 */
    const onMouseDown = React.useCallback((e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {

        startingPoint.current.x = e.clientX;
        startingPoint.current.y = e.clientY;

        originalPoint.current.x = task.width;
        originalPoint.current.y = task.height;

        window.document.body.addEventListener('mousemove', onMousemove)
        window.document.body.addEventListener('mouseup', onMouseup)

        function onMousemove(e: MouseEvent) {
            Controller.instance.run(async s => {
                const px = e.clientX - startingPoint.current.x;
                const py = e.clientY - startingPoint.current.y;

                let newX = originalPoint.current.x + px;
                let newY = originalPoint.current.y + py;

                if (newX < 200) newX = 200;
                if (newY < 120) newY = 120;

                task.isZoomX && (task.width = newX);
                task.isZoomY && (task.height = newY);
                s.taskInfo.list = [...s.taskInfo.list]
            })
        }

        function onMouseup() {
            window.document.body.removeEventListener('mousemove', onMousemove)
            window.document.body.removeEventListener('mouseup', onMouseup)
        }
    }, [task])


    if (task.isZoomX || task.isZoomY) {
        return (
            <Icon
                onMouseDown={onMouseDown}
                className={styles.zoom}
                component={I002Svg}
                style={{ fontSize: 18 }}
            />
        )
    } else {
        return (
            <></>
        )
    }
}

/** 删除按钮 */
function Close(props: { setShow: React.Dispatch<React.SetStateAction<boolean>> }) {

    const { delTask } = useTask();

    const { setShow } = props;

    const onClick = React.useCallback(async () => {
        setShow(false);
        await suspend(250);
        delTask();
    }, [delTask, setShow])

    return (
        <Icon className={styles.close} component={I001Svg} onClick={onClick} />
    )
}

/** 拖动逻辑 */
function useDrag() {

    const { task } = useTask();

    /** 鼠标启示位置 */
    const startingPoint = React.useRef({ x: 0, y: 0 })

    /** 窗口原始位置 */
    const originalPoint = React.useRef({ x: 0, y: 0 })

    /** 鼠标按下 */
    const onMouseDown = React.useCallback((e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {

        startingPoint.current.x = e.clientX;
        startingPoint.current.y = e.clientY;

        originalPoint.current.x = task.x;
        originalPoint.current.y = task.y;

        window.document.body.addEventListener('mousemove', onMousemove)
        window.document.body.addEventListener('mouseup', onMouseup)

        function onMousemove(e: MouseEvent) {
            Controller.instance.run(async s => {
                const px = e.clientX - startingPoint.current.x;
                const py = e.clientY - startingPoint.current.y;

                const newX = originalPoint.current.x + px;
                let newY = originalPoint.current.y + py;

                if (newY < 0) newY = 0;

                task.x = newX;
                task.y = newY;
                s.taskInfo.list = [...s.taskInfo.list]
            })
        }

        function onMouseup() {
            window.document.body.removeEventListener('mousemove', onMousemove)
            window.document.body.removeEventListener('mouseup', onMouseup)
        }
    }, [task])

    return {
        onMouseDown
    }
}